#include <iostream>

using namespace std;

/*
 * 多态
 *  静态多态 函数重载和运算符重载属于静态多态，服用函数名
 *  动态多态 派生类和虚函数实现运行时多态
 * 区别
 *  静态多态的函数地址早绑定    编译阶段确定函数地址
 *  动态多态的函数地址晚绑定    运行阶段确定函数地址
 */

/*
 * 动态多态满足条件
 *  1、有继承关系
 *  2、子类重写父类的虚函数
 *
 * 动态多态使用
 *  父类的指针或者引用 指向子类对象
 */
class Animal{
public:
    virtual void speak(){  // 若不使用virtual则为地址早绑定  使用virtual后，此处是一个vfptr(virtual function pointer)指向虚函数表(vftable)中实际的函数地址
        cout << "动物在说话" << endl;
    }
};

class Cat: public Animal{
public:
    void speak(){   // 当子类重写父类的虚函数，子类中的虚函数表(vftable)内部会替换成子类的虚函数地址
        cout << "小猫在说话" << endl;
    }
};

void doSpeak(Animal & animal) {
    animal.speak();
}

void test01(){
    Cat cat;
    doSpeak(cat);
}

int main() {

    test01();

    return 0;
}
